import { SuperMap3D } from '@/utils/supermap3d';

/**
 * 测量工具类 此方法结合了 Pinia 状态管理库 做成了组件化的测量工具类
 * 使用方式：
 * import { MeasureTool } from '@/utils/MeasureTool';
 *
 * let measureTool: MeasureTool;
 *
 * onMounted(() => {
 *   measureTool = new MeasureTool(viewer); // 传入你的 viewer 实例
 * });
 * // 测量距离
 * function startDistanceMeasure() {
 *   measureTool.startMeasure('distance');
 * }
 * // 面积测量
 * function startAreaMeasure() {
 *   measureTool.startMeasure('area');
 * }
 *
 * // 高度测量
 * function startHeightMeasure() {
 *   measureTool.startMeasure('height');
 * }
 *
 * // 清除测量
 * function clearMeasure() {
 *   measureTool.clear();
 * }
 *
 * 采用模块化和类型安全设计（使用 TypeScript）
 *
 * 结合 Pinia 来进行 SuperMap 测量工具的 统一状态管理和调用控制
 *
 * 主组件或地图组件中初始化 Viewer之后然后注册给 Pinia
 * import { useMeasureStore } from '@/stores/supermap/useMeasureStore';
 * import { onMounted } from 'vue';
 *
 * onMounted(() => {
 *   const viewer = new SuperMap3D.Viewer('mapContainer', { ... });
 *   const measureStore = useMeasureStore();
 *   measureStore.initMeasureTool(viewer);
 * });
 *
 */

export type MeasureType = 'distance' | 'area' | 'height';

export class MeasureTool {
  private viewer: any;
  private clampMode = 0; // 空间模式
  private handlerDis: any | null = null; // SuperMap3D.MeasureHandler
  private handlerArea: any | null = null;
  private handlerHeight: any | null = null;

  constructor(viewer: any) {
    this.viewer = viewer;
    this.initHandlers();
  }

  private activeMouse(isActive: boolean) {
    if (isActive) {
      this.viewer.enableCursorStyle = false;
      this.viewer._element.style.cursor = '';
      document.body.classList.remove('measureCur');
      document.body.classList.add('measureCur');
      this.viewer.scene.pickPointEnabled = true;
    } else {
      this.viewer.enableCursorStyle = true;
      document.body.classList.remove('measureCur');
      this.viewer.scene.pickPointEnabled = false;
    }
  }

  private initHandlers() {
    // 距离
    this.handlerDis = new SuperMap3D.MeasureHandler(this.viewer, SuperMap3D.MeasureMode.Distance, this.clampMode);
    this.handlerDis.measureEvt.addEventListener((result) => {
      const dis = Number(result.distance);
      const distance = dis > 1000 ? (dis / 1000).toFixed(2) + 'km' : dis.toFixed(2) + 'm';
      this.handlerDis!.disLabel.text = '距离: ' + distance;
    });
    this.handlerDis.activeEvt.addEventListener((isActive) => this.activeMouse(isActive));

    // 面积
    this.handlerArea = new SuperMap3D.MeasureHandler(this.viewer, SuperMap3D.MeasureMode.Area, this.clampMode);
    this.handlerArea.measureEvt.addEventListener((result) => {
      const mj = Number(result.area);
      const area = mj > 1000000 ? (mj / 1000000).toFixed(2) + 'km²' : mj.toFixed(2) + '㎡';
      this.handlerArea!.areaLabel.text = '面积: ' + area;
    });
    this.handlerArea.activeEvt.addEventListener((isActive) => this.activeMouse(isActive));

    // 高度
    this.handlerHeight = new SuperMap3D.MeasureHandler(this.viewer, SuperMap3D.MeasureMode.DVH, this.clampMode);
    this.handlerHeight.measureEvt.addEventListener((result) => {
      const distance = result.distance > 1000 ? (result.distance / 1000).toFixed(2) + 'km' : result.distance + 'm';
      const vHeight = result.verticalHeight > 1000 ? (result.verticalHeight / 1000).toFixed(2) + 'km' : result.verticalHeight + 'm';
      const hDistance = result.horizontalDistance > 1000 ? (result.horizontalDistance / 1000).toFixed(2) + 'km' : result.horizontalDistance + 'm';

      this.handlerHeight!.disLabel.text = '空间距离: ' + distance;
      this.handlerHeight!.vLabel.text = '垂直高度: ' + vHeight;
      this.handlerHeight!.hLabel.text = '水平距离: ' + hDistance;
    });
    this.handlerHeight.activeEvt.addEventListener((isActive) => this.activeMouse(isActive));
  }

  public startMeasure(type: MeasureType) {
    this.clear(); // 先关闭其他测量
    switch (type) {
      case 'distance':
        this.handlerDis?.activate();
        break;
      case 'area':
        this.handlerArea?.activate();
        break;
      case 'height':
        this.handlerHeight?.activate();
        break;
    }
  }

  public clear() {
    this.handlerDis?.clear();
    this.handlerDis?.deactivate();
    this.handlerArea?.clear();
    this.handlerArea?.deactivate();
    this.handlerHeight?.clear();
    this.handlerHeight?.deactivate();
    this.activeMouse(false);
  }

  public destroy() {
    this.handlerDis?.destroy();
    this.handlerArea?.destroy();
    this.handlerHeight?.destroy();
  }
}
